/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package logic;

import java.util.Arrays;
import weka.core.Instance;
import weka.core.Instances;


/**
 *
 * @author danielginting
 */

class kNNhelper implements Comparable<kNNhelper> {
    public int idx;
    public int dist;
    public char label;

    @Override
    public int compareTo(kNNhelper t) {
        int compareDist = ((kNNhelper) t).dist;
        // ascending order
        return this.dist - compareDist;
    }
    
}

public class MushroomkNN extends MushroomClassifier {
    
    private static int k;
    public MushroomkNN(int _k) {
        MushroomkNN.k = _k;
    }
    
    public static int getDistance(Instance training, Instance test) {
        int val = 0;
        String[] temp = training.toString().split(",");
        char[] training_attr = new char[temp.length];
        
        for (int i=0;i<temp.length;i++) {
            training_attr[i] = temp[i].charAt(0);
        }
        
        temp = test.toString().split(",");
        char[] test_attr = new char[temp.length];
        
        for (int i=0;i<temp.length;i++) {
            test_attr[i] = temp[i].charAt(0);
        }
        
        for (int i=0;i<training_attr.length;i++) {
            if (training_attr[i] != test_attr[i]) {
                val++;
            }
        }
                
        return val;
    }
    
    public int[] getAllDistance(Instances training, Instance test) {
        int[] val = new int[training.numInstances()];
        
        for (int i=0;i<training.numInstances();i++) {
            val[i] = getDistance(training.instance(i), test);
        }
        return val;        
    }
    
    public static char classify(Instances training, Instance test) {
        String[] temp = training.toString().split(",");
        int lastAttributeIdx = temp.length - 1;
        
        kNNhelper[] help = new kNNhelper[training.numInstances()];
        
        int[] k_class = new int[MushroomInfo.CLASS_VALUES_SHORT.length];
        for (int i=0;i<k_class.length;i++) {
            k_class[i] = 0;
        }
//        System.out.println("k_class size = " + k_class.length + "\n");
//        System.out.println("Num_instances = " + training.numInstances() + "\n");
//        System.out.println("idx \t dist\n");
        
        for (int i=0;i<training.numInstances();i++) {
            help[i] = new kNNhelper();
            help[i].idx = i;
            help[i].dist = getDistance(training.instance(i), test);
            String s = training.instance(i).toString();
            help[i].label = s.substring(s.length()-1, s.length()).charAt(0);
//            System.out.println(help[i].idx + "\t" + help[i].dist + " \t" + help[i].label + "\n");
        }

        Arrays.sort(help);

        // count label for k - lowest distance instance
        for (int i=0;i<k;i++) {
            for (int j=0;j<MushroomInfo.CLASS_VALUES_SHORT.length;j++) {
                if (help[i].label==MushroomInfo.CLASS_VALUES_SHORT[j]) {
                    k_class[j]++;
                }
            }
        }
        
        int max = k_class[0];
        int idx = 0;
        for (int i=0;i<k_class.length;i++) {
            if (k_class[i] > max) {
                idx = i;
            }
        }
        
        return MushroomInfo.CLASS_VALUES_SHORT[idx];        
    }

    @Override
    public void buildClassifier(Instances i) throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    public static void main(String[] args) {
        MushroomkNN kNN = new MushroomkNN(7);
        Instances inst = Loader.load("/Users/danielginting/Desktop/mushroom.arff");
        char value = '\0';
       
        value = classify(inst,inst.instance(1));
   
        System.out.println("Isinya : " + value + "\n");
   }

    @Override
    public char classify(Instance in) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public char classify(Instance in, boolean[] selectionAttrs) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
